import { Injectable } from '@nestjs/common';
import { CreateSysMenuDto } from './dto/create-sys-menu.dto';
import { UpdateSysMenuDto } from './dto/update-sys-menu.dto';
import { Repository } from 'typeorm';
import { SysMenu } from './entities/sys-menu.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { SysUser } from '../sys-user/entities/sys-user.entity';
import { RouterVo } from './vo/router.vo';
import {
  capitalizeFirstLetter,
  innerLinkReplaceEach,
} from '../../utils/conversion';
import { isHttpOrHttpsLink } from '../../utils/validate';
import { UserConstants } from '../../constants/user-constants';
import {
  getComponent,
  getRouteName,
  getRouterPath,
  isInnerLink,
  isMenuFrame,
} from '../../utils/index.utils';

@Injectable()
export class SysMenuService {
  constructor(
    @InjectRepository(SysMenu)
    private readonly sysMenuRepository: Repository<SysMenu>,
  ) {}

  //  根据roleId获取菜单权限
  async selectMenuPermsByRoleId(roleId: number): Promise<any> {
    const perms = await this.sysMenuRepository
      .createQueryBuilder('menu')
      .leftJoinAndSelect('menu.roles', 'roles')
      .where('roles.role_id = :role_id and menu.perms != "" ', {
        role_id: roleId,
      })
      .getMany();
    return perms.map((item) => {
      return item.perms;
    });
  }

  // 获取路由信息
  async selectMenuTreeByUserId(userId: number) {
    let menus = [];
    // 根据用户id获取菜单
    if (SysUser.isAdmin(userId)) {
      menus = await this.sysMenuRepository.find({
        where: {
          status: '0',
        },
        order: {
          menu_id: 'ASC',
        },
      });
    } else {
      menus = await this.sysMenuRepository
        .createQueryBuilder('m')
        .leftJoin('m.roles', 'mr')
        .leftJoin('mr.users', 'mru')
        .where('mru.user_id = :userId', { userId })
        .andWhere('m.menu_type in (:types)', { types: ['M', 'C'] })
        .andWhere('m.status = :status', { status: 0 })
        .andWhere('mr.status = :status', { status: 0 })
        .getMany();
    }
    return this.buildTreeMenu(menus);
  }

  // 构建返回路由数据
  buildMenus(menus: SysMenu[]): RouterVo[] {
    const routers: RouterVo[] = [];
    for (const menu of menus) {
      let router: RouterVo = {
        hidden: menu.visible === '1',
        name: getRouteName(menu),
        path: getRouterPath(menu),
        component: getComponent(menu),
        query: menu.query,
        meta: {
          title: menu.menu_name,
          icon: menu.icon,
          noCache: menu.is_cache === 1,
          link: isHttpOrHttpsLink(menu.path) ? menu.path : null,
        },
      };
      const cMenus: SysMenu[] = menu.children;
      if (cMenus && menu.menu_type === UserConstants.TYPE_DIR) {
        router.alwaysShow = true;
        router.redirect = 'noRedirect';
        router.children = this.buildMenus(cMenus);
      } else if (isMenuFrame(menu)) {
        const childrenList: RouterVo[] = [];
        const children: any = {
          path: menu.path,
          component: menu.component,
          name: capitalizeFirstLetter(menu.path),
          meta: {
            title: menu.menu_name,
            icon: menu.icon,
            noCache: menu.is_cache === 1,
            path: isHttpOrHttpsLink(menu.path) ? menu.path : null,
          },
          query: menu.query,
        };
        childrenList.push(children);
        router.children = childrenList;
      } else if (menu.parent_id == 0 && isInnerLink(menu)) {
        router = {
          children: [],
          meta: {
            title: menu.menu_name,
            icon: menu.icon,
          },
          path: '/',
        };
        const childrenList: RouterVo[] = [];
        const children: RouterVo = {
          children: [],
          path: innerLinkReplaceEach(menu.path),
          component: UserConstants.INNER_LINK,
          name: capitalizeFirstLetter(menu.path),
          meta: {
            title: menu.menu_name,
            icon: menu.icon,
            path: menu.path,
          },
        };
        childrenList.push(children);
        router.children = childrenList;
      }
      routers.push(router);
    }
    return routers;
  }

  // 构建树形菜单
  buildTreeMenu(menuData: SysMenu[], parentId: number = 0) {
    const menuTree = [];
    for (let i = 0; i < menuData.length; i++) {
      const menu = menuData[i];
      if (menu.parent_id === parentId) {
        const children = this.buildTreeMenu(menuData, menu.menu_id);
        if (children.length > 0) {
          menu.children = children;
        }
        menuTree.push(menu);
      }
    }
    return menuTree;
  }
  create(createSysMenuDto: CreateSysMenuDto) {
    return 'This action adds a new sysMenu';
  }

  findAll() {
    return `This action returns all sysMenu`;
  }

  findOne(id: number) {
    return `This action returns a #${id} sysMenu`;
  }

  update(id: number, updateSysMenuDto: UpdateSysMenuDto) {
    return `This action updates a #${id} sysMenu`;
  }

  remove(id: number) {
    return `This action removes a #${id} sysMenu`;
  }
}
